package model;

import ai.EasyAI;
import ai.HardAI;
import ai.NormalAI;

/**
 * 对于棋盘的操作类.
 *
 * @author 任禹名
 */
public class ChessAction {

    private int i, j, cnt;
    private final int WHITE = 2, BLACK = 1;
    private int[][] nowTable = new int[15][15];
    private int[][] stackTable = new int[260][2];
    private int stackCnt = -1;
    private EasyAI easyAI = EasyAI.getInstance(this);
    private NormalAI normalAI = NormalAI.getInstance(this);
    private HardAI hardAI = HardAI.getInstance(this);
    private ChessBoard chessBoard;

    public int[][] getNowTable() {
        return nowTable;
    }

    public void setChessBoard(ChessBoard chessBoard) {
        this.chessBoard = chessBoard;
    }

    /**
     * 在棋盘上标记落子.
     *
     * @param x
     * @param y
     * @param chessColor
     * @return 是否落子成功.
     * @author 任禹名
     */
    public boolean downChess(int x, int y, int chessColor) {
        if (nowTable[x][y] != 0) {
            return false;
        } else {
            stackCnt++;
            stackTable[stackCnt][0] = x;
            stackTable[stackCnt][1] = y;
            if (chessColor == WHITE) {
                nowTable[x][y] = WHITE;
            } else {
                nowTable[x][y] = BLACK;
            }

        }
        return true;
    }

    /**
     * 删除指定棋子.
     *
     * @param limit  剩余悔棋次数
     * @param amount 删除的棋子个数
     * @return 返回是否有剩余悔棋次数
     * @author 任禹名
     */
    public int deleteChess(int limit, int amount) {
        if (limit <= 0) {
            return -1;
        } else {
            for (; amount != 0; amount--) {
                if (stackCnt < 0)
                    return 0;
                if (stackCnt == 0) {
                    easyAI.setFirst(true);
                    normalAI.setStarted(true);
                }
                if (chessBoard.getMode() == 1) {
                    easyAI.delete(stackTable[stackCnt][0], stackTable[stackCnt][1]);
                } else if (chessBoard.getMode() == 2) {
                    normalAI.delete(stackTable[stackCnt][0], stackTable[stackCnt][1]);
                } else if (chessBoard.getMode() == 3) {
                    hardAI.delete(stackTable[stackCnt][0], stackTable[stackCnt][1]);
                }

                nowTable[stackTable[stackCnt][0]][stackTable[stackCnt][1]] = 0;
                stackCnt--;
            }
        }
        return 1;
    }

    /**
     * 判断是否有一方获胜.
     *
     * @param x
     * @param y
     * @return 是否获胜
     * @author 任禹名
     */
    public boolean isWin(int x, int y) {
        //竖直
        cnt = 1;
        for (i = x, j = y; j > 0 && nowTable[i][j] == nowTable[i][j - 1]; j--) {
            cnt++;
        }
        for (i = x, j = y; j < 14 && nowTable[i][j] == nowTable[i][j + 1]; j++) {
            cnt++;
        }
        if (cnt >= 5) {
            return true;
        }
        //水平
        cnt = 1;
        for (i = x, j = y; i > 0 && nowTable[i][j] == nowTable[i - 1][j]; i--) {
            cnt++;
        }
        for (i = x, j = y; i < 14 && nowTable[i][j] == nowTable[i + 1][j]; i++) {
            cnt++;
        }
        if (cnt >= 5) {
            return true;
        }
        //右上左下
        cnt = 1;
        for (i = x, j = y; i < 14 && j > 0 && nowTable[i][j] == nowTable[i + 1][j - 1]; i++, j--) {
            cnt++;
        }
        for (i = x, j = y; j < 14 && i > 0 && nowTable[i][j] == nowTable[i - 1][j + 1]; i--, j++) {
            cnt++;
        }
        if (cnt >= 5) {
            return true;
        }
        //右下左上
        cnt = 1;
        for (i = x, j = y; i < 14 && j < 14 && nowTable[i][j] == nowTable[i + 1][j + 1]; i++, j++) {
            cnt++;
        }
        for (i = x, j = y; i > 0 && j > 0 && nowTable[i][j] == nowTable[i - 1][j - 1]; i--, j--) {
            cnt++;
        }
        if (cnt >= 5) {
            return true;
        }
        return false;
    }

    /**
     * 重置棋盘所有数据
     *
     * @author 任禹名
     */
    public void reset() {
        this.cnt = 0;
        this.stackCnt = -1;
        easyAI.reset(this);
        normalAI.reset(this);
        hardAI.reset(this);
        for (i = 0; i < 15; i++) {
            for (j = 0; j < 15; j++) {
                nowTable[i][j] = 0;
            }
        }
        for (i = 0; i < 255; i++) {
            stackTable[i][0] = 0;
            stackTable[i][1] = 0;
        }
        this.i = 0;
        this.j = 0;
        return;
    }

    /**
     * AI计算落子.
     *
     * @param x
     * @param y
     * @param degree
     * @param chessColor
     * @return Ai计算出的坐标
     * @author 任禹名
     */
    public int[] downChessByAI(int x, int y, int degree, int chessColor) {
        int[] result = new int[2];
        if (degree == 1) {
            result = easyAI.downChess(chessColor);
        } else if (degree == 2) {
            normalAI.initBeforeDownChess(x, y);
            result = normalAI.downChess(chessColor);
        } else {
            result = hardAI.downChess(chessColor);
        }

        return result;
    }
}
